package com.example;

import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.text.XSentenceCursor;
import com.sun.star.text.XText;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextDocument;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JFrame;
import javax.swing.JOptionPane;


public final class ProbaAddOn3 extends WeakBase
   implements com.sun.star.lang.XInitialization,
              com.sun.star.frame.XDispatch,
              com.sun.star.lang.XServiceInfo,
              com.sun.star.frame.XDispatchProvider
{
    private final XComponentContext m_xContext;
    private static com.sun.star.frame.XFrame m_xFrame;
    private static final String m_implementationName = ProbaAddOn3.class.getName();
    private static final String[] m_serviceNames = {
        "com.sun.star.frame.ProtocolHandler" };


    public ProbaAddOn3( XComponentContext context )
    {
        m_xContext = context;
    };

    public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
        XSingleComponentFactory xFactory = null;

        if ( sImplementationName.equals( m_implementationName ) )
            xFactory = Factory.createComponentFactory(ProbaAddOn3.class, m_serviceNames);
        return xFactory;
    }

    public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) {
        return Factory.writeRegistryServiceInfo(m_implementationName,
                                                m_serviceNames,
                                                xRegistryKey);
    }

    // com.sun.star.lang.XInitialization:
    public void initialize( Object[] object )
        throws com.sun.star.uno.Exception
    {
        if ( object.length > 0 )
        {
            m_xFrame = (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(
                com.sun.star.frame.XFrame.class, object[0]);
        }
    }
    public static XText xText;
    public static String command = "";
    public static boolean web = false;
    // com.sun.star.frame.XDispatch:
     public void dispatch( com.sun.star.util.URL aURL,
                           com.sun.star.beans.PropertyValue[] aArguments )
    {
         if ( aURL.Protocol.compareTo("com.example.probaaddon3:") == 0 )
        {
            if ( aURL.Path.compareTo("Launch app") == 0 )
            {
                // add your own code here
                JFrame gui = new GUI();
                gui.setVisible(true);
                gui.toFront();
                return;
            }
            if ( aURL.Path.compareTo("DRS-XML") == 0 )
            {
                // add your own code here
                web = false;
                command = "cdrsxml";
                doWork("cdrsxml", false);
                return;
            }
            if ( aURL.Path.compareTo("OWL-RDF") == 0 )
            {
                command = "cowlrdf";
                web = false;
                doWork("cowlrdf", false);
                return;
            }

            if ( aURL.Path.compareTo("OWL-XML") == 0 )
            {
                // add your own code here
                web = false;
                command = "cowlxml";
                doWork("cowlxml", false);
                return;
            }
            if ( aURL.Path.compareTo("[web]OWL-RDF") == 0 )
            {
                // add your own code here
                web = true;
                command = "cowlrdf";
                doWork("cowlrdf", true);
                return;
            }
            if ( aURL.Path.compareTo("[web]DRS-XML") == 0 )
            {
                // add your own code here
                web = true;
                command = "cdrsxml";
                doWork("cdrsxml", true);
                return;
            }
            if ( aURL.Path.compareTo("[web]OWL-XML") == 0 )
            {
                // add your own code here
                web = true;
                command = "cowlxml";
                doWork("cowlxml", true);
                return;
            }
        }
    }

    public void addStatusListener( com.sun.star.frame.XStatusListener xControl,
                                    com.sun.star.util.URL aURL )
    {
        // add your own code here
    }

    public void removeStatusListener( com.sun.star.frame.XStatusListener xControl,
                                       com.sun.star.util.URL aURL )
    {
        // add your own code here
    }

    // com.sun.star.lang.XServiceInfo:
    public String getImplementationName() {
         return m_implementationName;
    }

    public boolean supportsService( String sService ) {
        int len = m_serviceNames.length;

        for( int i=0; i < len; i++) {
            if (sService.equals(m_serviceNames[i]))
                return true;
        }
        return false;
    }

    public String[] getSupportedServiceNames() {
        return m_serviceNames;
    }

    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch queryDispatch( com.sun.star.util.URL aURL,
                                                       String sTargetFrameName,
                                                       int iSearchFlags )
    {
        if ( aURL.Protocol.compareTo("com.example.probaaddon3:") == 0 )
        {
            if ( aURL.Path.compareTo("Launch app") == 0 )
                return this;
            if ( aURL.Path.compareTo("DRS-XML") == 0 )
                return this;
            if ( aURL.Path.compareTo("OWL-RDF") == 0 )
                return this;
            if ( aURL.Path.compareTo("OWL-XML") == 0 )
                return this;
            if ( aURL.Path.compareTo("[web]OWL-RDF") == 0 )
                return this;
            if ( aURL.Path.compareTo("[web]DRS-XML") == 0 )
                return this;
            if ( aURL.Path.compareTo("[web]OWL-XML") == 0 )
                return this;
        }
        return null;
    }

    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch[] queryDispatches(
         com.sun.star.frame.DispatchDescriptor[] seqDescriptors )
    {
        int nCount = seqDescriptors.length;
        com.sun.star.frame.XDispatch[] seqDispatcher =
            new com.sun.star.frame.XDispatch[seqDescriptors.length];

        for( int i=0; i < nCount; ++i )
        {
            seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,
                                             seqDescriptors[i].FrameName,
                                             seqDescriptors[i].SearchFlags );
        }
        return seqDispatcher;
    }

    protected static String APE(String input, String type) {
         String str = input;
         boolean errGlob = false;
         String rez = "";
         String error = "";
         type = type.trim();
        try {
            //Process proc = Runtime.getRuntime().exec("mspaint"); //proba dali funkcionira. Pushta bilo koe .exe
//            String comm = ""; //komanda za da se dade na ape.exe
//            //comm += "C:\\Users\\Solev\\Desktop\\WBS_sem\\ape\\ape.exe"; //kade e ape.exe, treba da se smeni vo zavisnost od PC, ili so relativna da se proba
//
//            comm += "ape.exe";
//
//            comm += " -text"; //kje obrabotuvame tekst od tekstboksot
//            comm += " \"" + str + "\""; //tekstot od tekstboksot
//
//            comm += " -cowlrdf"; //cowlrdf, cdrsxml

            //Process proc = Runtime.getRuntime().exec(comm);
            Process proc = Runtime.getRuntime().exec("C:\\Users\\Solev\\Desktop\\WBS_sem\\ape\\ape.exe -text \"" + str + "\"" + " -" + type);
            //txaResult.append(proc.getInputStream().toString() + "\n");
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));

            String line = null;

            boolean err = false;
            while ((line = in.readLine()) != null) {
                line = line.replace("&gt;", ">");
                line = line.replace("&lt;", "<");
                if(line.contains("<messages>"))
                {err = true; errGlob = true;}
                else if(line.contains("</messages>")) err = false;
                if(err || line.contains("</messages>")) error += line + " \n";
                else
                rez += line + "\n";
            }

            proc.destroy();

        } catch (java.lang.Exception ex) {
            System.out.print(ex.toString());
        }
         if(errGlob) return "error" + error; else return "result" + rez;
    }

    protected static void obrabotiGreshka2 (String err) {
        String greshka = err;
        err = err.replaceFirst("error", "");
        err = err.replaceAll("<messages>", ""); //chistenje na tagovite za poraki
        err = err.replaceAll("</messages>","");
        err = err.replaceAll("/>", "");
        String[] sodrzina = err.split("<message "); //delenje kaj tagot za sekoja poedinechna poraka
                                                    //gi izdvojuvame site poraki

        Integer a = sodrzina.length;
        Integer nErr = sodrzina.length - 1; //broj na poraki
        for(int i = 0; i < sodrzina.length; i++)
            sodrzina[i] = sodrzina[i].trim();       //trganje na praznite mesta

            try {
            XComponent xWriterComponent = m_xFrame.getController().getModel();
            XMultiServiceFactory mxDocFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(XMultiServiceFactory.class, xWriterComponent);
            XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xWriterComponent);
            XText mxDocText = xTextDocument.getText();
            XTextCursor mxDocCursor = mxDocText.createTextCursor();

            String text = mxDocText.getString();
            Integer count = 0;
            String regex = "[^\\.!\\?\\n]*[\\.!\\?\\n]\\s*";
                Pattern p = Pattern.compile(regex);
                Matcher m = p.matcher(text);
                while(m.find()) {
                    count++;
                }

            mxDocCursor.gotoStart(false);

            XSentenceCursor xSentenceCursor = (XSentenceCursor)UnoRuntime.queryInterface(XSentenceCursor.class, mxDocCursor);

            xSentenceCursor.gotoStart(false);

            XPropertySet xCursorProps = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xSentenceCursor);

            for(int i = 1; i <= count; i++) {
                boolean er = false;
                for(int j = 1; j <= nErr; j++)
                    if(sodrzina[j].contains("sentence=\""+i+"\""))
                    {er = true; break;}

                if(er) {
                    xSentenceCursor.gotoEndOfSentence(true);
                    xCursorProps.setPropertyValue("CharUnderline", com.sun.star.awt.FontUnderline.WAVE);
                }
                else {
                    xSentenceCursor.gotoEndOfSentence(true);
                    xCursorProps.setPropertyValue("CharUnderline", com.sun.star.awt.FontUnderline.NONE);
                }
               xSentenceCursor.gotoNextSentence(false);
               xSentenceCursor.gotoStartOfSentence(false);
            }

            JFrame grsh = new ErrCorrect(greshka);
            grsh.setVisible(true);
            grsh.toFront();
            }
            catch (Exception e) {
                System.out.print(e.toString());
            }
    }

    protected static String webAPE(String input, String type) {
        
        boolean errGlob = false;
        String rez = "";
        String error = "";
        if(input.length() > 0)
        {
            try { 
                
                //input = input.replace(' ', '+');
                input = URLEncoder.encode(input, "UTF-8");
         
                URL url = new URL("http://attempto.ifi.uzh.ch/ws/ape/apews.perl?text=" + input + "&" + type + "=on");
                URLConnection connection = url.openConnection();

                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line = null;

            boolean err = false;
            while ((line = reader.readLine()) != null) {
                line = line.replace("&gt;", ">");
                line = line.replace("&lt;", "<");
                if(line.contains("<messages>"))
                {err = true; errGlob = true;}
                else if(line.contains("</messages>")) err = false;
                if(err || line.contains("</messages>")) error += line + " \n";
                else
                rez += line + "\n";
            }
           
            }
            catch(StringIndexOutOfBoundsException e){
                System.err.println("Error: " + e.getMessage());
                JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
            catch(Exception e){
                System.err.println("Error: " + e.getMessage());
                JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        }

        if(errGlob) return "error" + error; else return "result" + rez;
        //http://attempto.ifi.uzh.ch/ws/ape/apews.perl?text=Every+man+is+a+human.&cowlrdf=on
    }

    protected static void doWork (String command, boolean web) {
                XTextDocument xDoc = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, m_xFrame.getController().getModel());
                xText = xDoc.getText();
                try {
                    XComponent xWriterComponent = m_xFrame.getController().getModel();
                    XMultiServiceFactory mxDocFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(XMultiServiceFactory.class, xWriterComponent);
                    XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xWriterComponent);
                    XText mxDocText = xTextDocument.getText();
                    XTextCursor mxDocCursor = mxDocText.createTextCursor();

                    String rezultat = "";
                    if(web) rezultat = webAPE(xText.getString(), command);
                    else rezultat = APE(xText.getString(), command);
                    if(rezultat.startsWith("error")) {
                        obrabotiGreshka2(rezultat);
                    }
                    else {
                        mxDocCursor.gotoStart(false);
                        mxDocCursor.gotoEnd(true);
                        XPropertySet xCursorProps = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, mxDocCursor);
                        xCursorProps.setPropertyValue("CharUnderline", com.sun.star.awt.FontUnderline.NONE);
                        JFrame ok = new InfoXMLfile(rezultat);
                        ok.setVisible(true);
                        ok.toFront();
                    }
                }

                catch (java.lang.Exception ex) {
                    Logger.getLogger(ProbaAddOn3.class.getName()).log(Level.SEVERE, null, ex);
                }
    }

}
